package com.gxdf.extendedcontrols.gxdfclient;

import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;

import json.org.json.JSONArray;

import org.json.JSONException;
import org.json.JSONObject;







import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.AssetManager;
import android.text.Html;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;

import com.artech.R;
import com.artech.base.controls.IGxControlRuntime;
import com.artech.base.metadata.layout.ControlInfo;
import com.artech.base.metadata.layout.LayoutItemDefinition;
import com.artech.base.services.Services;
import com.artech.controls.IGxEdit;
import com.google.gson.stream.JsonWriter;
import com.gxdf.extendedcontrols.gxdfclient.components.GxdfConceptContainer;
import com.gxdf.extendedcontrols.gxdfclient.components.GxdfField;
import com.gxdf.extendedcontrols.gxdfclient.components.GxdfForm;
import com.gxdf.extendedcontrols.gxdfclient.components.GxdfMapDialog;
import com.gxdf.extendedcontrols.gxdfclient.components.GxdfStoredValues;
import com.gxdf.extendedcontrols.gxdfclient.components.IGxdfItem;
import com.gxdf.extendedcontrols.gxdfclient.data.Field;
import com.gxdf.extendedcontrols.gxdfclient.data.Form;
import com.gxdf.extendedcontrols.gxdfclient.data.ValidationResult;
import com.gxdf.extendedcontrols.gxdfclient.services.FormToGxForm;
import com.gxdf.extendedcontrols.gxdfclient.services.JsonToForm;

public class SDGxdf extends LinearLayout implements IGxEdit, IGxControlRuntime {

	public static final String METHOD_VALIDATE = "Validate";
	public static final String PROP_ISVALID = "IsValid";
	public static final String PROP_VALUE = "Value";
	Context mContext;
	GxdfForm gxdfForm;
	Button submitButton;
	List<ValidationResult> validResults;
	String jsonString;
	String jsonResult;
	boolean loaded = false;
	boolean isValid;

	public SDGxdf(Context context, LayoutItemDefinition def) {
		super(context);

		this.setPadding(10, 10, 10, 10);
		mContext = context;
		LayoutInflater inflater = (LayoutInflater) context
				.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		if (inflater != null) {
			inflater.inflate(R.layout.activity_form_render, this, true);

		}

		setLayoutDefintion(def);
	}


	private void setLayoutDefintion(LayoutItemDefinition def) {

		ControlInfo info = def.getControlInfo();
		if (info == null)
			return;
	}

	public void init() {

		// Main point
		loaded = true;
		validResults = new ArrayList<ValidationResult>();
		jsonResult = new String();
		Form form = JsonToForm.getForm(jsonString);
		gxdfForm = FormToGxForm.getGxForm(this.mContext, form);
		startRender(gxdfForm);

	}

	@SuppressLint("NewApi")
	private void startRender(GxdfForm form) {

		LinearLayout ly = (LinearLayout) findViewById(R.id.main_linear);
		List<IGxdfItem> fields = form.getFields();

		for (int i = 0; i < fields.size(); i++) {

			IGxdfItem item = fields.get(i);
			item.drawField();
			ly.addView((View) item);
		}

	}

	//Validate desde el SDPanel
	void execValidRules() {
		List<IGxdfItem> fields = gxdfForm.getFields();

		for (IGxdfItem f : fields) {
			f.saveValues();
			f.runValidationRules();
			if (!(f.isFieldvalid()))
				validResults.addAll(f.getValidationList());

		}

		if (validResults.size() > 0) {
			showErrors();
			validResults.clear();

		} else {
			validResults.clear();
			showResume();
		}

	}


	void showErrors() {
		StringBuilder sb = new StringBuilder();

		for (ValidationResult vr : validResults) {
			sb.append("Campo: " + vr.getFieldName() + " - " + vr.getVmessage()
					+ System.getProperty("line.separator"));
		}
		validResults.clear();

		AlertDialog.Builder builder = new AlertDialog.Builder(this.mContext);
		builder.setTitle("Error en los datos");
		builder.setMessage(sb.toString());
		builder.setNeutralButton("OK", new DialogInterface.OnClickListener() {

			@Override
			public void onClick(DialogInterface arg0, int arg1) {
				arg0.cancel();
			}
		});
		AlertDialog adialog = builder.create();
		adialog.show();

	}

	public void showResume() {

		validResults.clear();

		List<IGxdfItem> fields = gxdfForm.getFields();
		List<GxdfStoredValues> svalues = new ArrayList<GxdfStoredValues>();

		for (IGxdfItem f : fields) {

			f.saveValues();

			if (f instanceof GxdfConceptContainer) {

				List<Field> conceptList = ((GxdfConceptContainer) f)
						.getFields();

				for (Field cf : conceptList) {
					for (int i = 0; i < cf.getValues().size(); i++) {

						GxdfStoredValues sv = new GxdfStoredValues("Form",
								cf.getName(), String.valueOf(i + 1), cf
										.getValues().get(i));
						svalues.add(sv);
					}

				}

			}

			else {

				if (((GxdfField) f).getActualValues().size() == 0) {
					GxdfStoredValues sv = new GxdfStoredValues("Form",
							((GxdfField) f).getFieldName(), String.valueOf(0),
							"");
					svalues.add(sv);

				} else {

					for (int i = 0; i < f.getActualValues().size(); i++) {
						GxdfStoredValues sv = new GxdfStoredValues("Form",
								((GxdfField) f).getFieldName(),
								String.valueOf(i + 1), f.getActualValues().get(
										i));
						svalues.add(sv);
					}
				}

			}

		}

		// LinearLayout dialogLayout = new LinearLayout(this.mContext);
		ScrollView dialogLayout = new ScrollView(this.mContext);
		LinearLayout child = new LinearLayout(getContext());
		child.setOrientation(VERTICAL);
		dialogLayout.addView(child);

		for (GxdfStoredValues sv : svalues) {

			Activity a = (Activity) getContext();

			LinearLayout linear = (LinearLayout) a.getLayoutInflater().inflate(
					R.layout.result_view_layout, null);
			TextView labeltxt = (TextView) linear.findViewById(R.id.labeltxt);
			TextView valuetxt = (TextView) linear.findViewById(R.id.valuetxt);

			labeltxt.setText(sv.getFieldName() + ":");
			valuetxt.setText(sv.getValue());

			child.addView(linear);

		}

		AlertDialog.Builder builder = new AlertDialog.Builder(this.mContext);
		builder.setTitle("Confirmar Datos");
		builder.setView(dialogLayout);
		builder.setNeutralButton("Enviar",
				new DialogInterface.OnClickListener() {

					@Override
					public void onClick(DialogInterface arg0, int arg1) {

						SDGxdf.this.buildJson();
						arg0.cancel();
					}
				});
		AlertDialog adialog = builder.create();
		adialog.show();

	}

	private void invokeActivity(Activity a) {

		String actionName = "intent.action.CALL_PREVIEW";
		Intent intent = new Intent(actionName);
		a.startActivity(intent);
	}

	@Override
	public String getGx_Value() {
		return jsonResult;
	}

	@Override
	public void setGx_Value(String value) {
		if (Services.Strings.hasValue(value)) {
			jsonString = value;
		}
		
		if(!loaded)
			init();

	}

	@Override
	public String getGx_Tag() {
		// TODO Auto-generated method stub
		return getTag().toString();
	}

	@Override
	public void setGx_Tag(String tag) {
		// TODO Auto-generated method stub
		setTag(tag);

	}

	@Override
	public void setValueFromIntent(Intent data) {

	}

	@Override
	public boolean isEditable() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public IGxEdit getViewControl() {
		// TODO Auto-generated method stub
		return this;
	}

	@Override
	public IGxEdit getEditControl() {
		// TODO Auto-generated method stub
		return this;
	}


	@Override
	public void setProperty(String name, Object value) {
	}

	@Override
	public Object getProperty(String name) { 
		if(PROP_ISVALID.equalsIgnoreCase(name))
			return isValid; 
		else 
			if(PROP_VALUE.equalsIgnoreCase(name))
				return jsonResult; 
			else
				return null;
		 

	}

	@Override
	public void runMethod(String name, List<Object> parameters) {
		if(METHOD_VALIDATE.equalsIgnoreCase(name))
			execValidRules();
	}

	String returnUpdatedData() {

		StringBuilder sb = new StringBuilder();
		return sb.toString();
	}

		
	void buildJson (){
		
		List<IGxdfItem> fields = gxdfForm.getFields();
		StringWriter stringWriter = new StringWriter();
		JsonWriter writer = new JsonWriter(stringWriter);		
		
		try {
			writer.beginObject();
			writer.name("FormName");
			writer.value(gxdfForm.getName());
			writer.name("FormDescription").value(gxdfForm.getDescription());
			writer.name("InstanceName").value(gxdfForm.getInstanceName());
			writer.name("Fields");
			
			writer.beginArray();
			for (IGxdfItem f : fields) {
				f.saveValues();
				
				if(f instanceof GxdfConceptContainer)
				{
					
					for(int i=0;i<((GxdfConceptContainer)f).getFields().size();i++){
						
						((GxdfConceptContainer)f).buildJson(writer,i);
					}
					
				}
				else{							
					((GxdfField)f).buildjson(writer);					
					
				}
			}
			writer.endArray();
			writer.endObject();
			stringWriter.close();
			
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		jsonResult = stringWriter.toString();
		Log.i("JSON-Result", jsonResult);
		
	}

}
